import dynamic from 'next/dynamic' import NextImage from 'next/image'; import { useEffect, useState } from 'react' import { useRouter } from 'next/router' import Seo from '../../../core/components/Seo' import Promocrumb from '../../../lib/promo/components/Promocrumb' import { fetchPromoItemsSolr, fetchVariantSolr } from '../../../api/promoApi' import LogoSpinner from '../../../core/components/elements/Spinner/LogoSpinner.jsx' import ProductPromoCard from '../../../../src-migrate/modules/product-promo/components/Card' import { IPromotion } from '../../../../src-migrate/types/promotion' import React from 'react' import { SolrResponse } from "../../../../src-migrate/types/solr.ts"; import DesktopView from '../../../core/components/views/DesktopView'; import MobileView from '../../../core/components/views/MobileView'; import 'swiper/swiper-bundle.css'; import useDevice from '../../../core/hooks/useDevice' import ProductFilterDesktop from '../../../lib/product/components/ProductFilterDesktopPromotion'; import ProductFilter from '../../../lib/product/components/ProductFilter'; import { HStack, Image, Tag, TagCloseButton, TagLabel } from '@chakra-ui/react'; import { formatCurrency } from '../../../core/utils/formatValue'; import Pagination from '../../../core/components/elements/Pagination/Pagination'; import SideBanner from '../../../../src-migrate/modules/side-banner'; import whatsappUrl from '../../../core/utils/whatsappUrl'; import { cons, toQuery } from 'lodash-contrib'; import _ from 'lodash'; import useActive from '../../../core/hooks/useActive'; const BasicLayout = dynamic(() => import('../../../core/components/layouts/BasicLayout')) export default function PromoDetail() { const router = useRouter() const { slug = '', brand ='', category='', priceFrom = '', priceTo = '', page = '1' } = router.query const [promoItems, setPromoItems] = useState([]) const [promoData, setPromoData] = useState(null) const [currentPage, setCurrentPage] = useState(parseInt(page as string, 10) || 1); const itemsPerPage = 12; // Jumlah item yang ingin ditampilkan per halaman const [loading, setLoading] = useState(true); const { isMobile, isDesktop } = useDevice() const [brands, setBrands] = useState([]); const [categories, setCategories] = useState([]); const [brandValues, setBrandValues] = useState([]); const [categoryValues, setCategoryValues] = useState([]); const [orderBy, setOrderBy] = useState(router.query?.orderBy || 'popular'); const popup = useActive(); const prefixUrl = `/shop/promo/${slug}` useEffect(() => { if (router.query.brand) { let brandsArray: string[] = []; if (Array.isArray(router.query.brand)) { brandsArray = router.query.brand; } else if (typeof router.query.brand === 'string') { brandsArray = router.query.brand.split(',').map((brand) => brand.trim()); } setBrandValues(brandsArray); } else { setBrandValues([]); } if (router.query.category) { let categoriesArray: string[] = []; if (Array.isArray(router.query.category)) { categoriesArray = router.query.category; } else if (typeof router.query.category === 'string') { categoriesArray = router.query.category.split(',').map((category) => category.trim()); } setCategoryValues(categoriesArray); } else { setCategoryValues([]); } }, [router.query.brand, router.query.category]); interface Brand { brand: string; qty: number; } interface Category { name: string; qty: number; } useEffect(() => { const loadPromo = async () => { setLoading(true); const brandsData: Brand[] = []; const categoriesData: Category[] = []; const pageNumber = Array.isArray(page) ? parseInt(page[0], 10) : parseInt(page, 10); setCurrentPage(pageNumber) try { const items = await fetchPromoItemsSolr(`type_value_s:${Array.isArray(slug) ? slug[0] : slug}`,0,100); setPromoItems(items); if (items.length === 0) { setPromoData([]) setLoading(false); return; } const brandArray = Array.isArray(brand) ? brand : brand.split(','); const categoryArray = Array.isArray(category) ? category : category.split(','); const promoDataPromises = items.map(async (item) => { try { let brandQuery = ''; if (brand) { brandQuery = brandArray.map(b => `manufacture_name_s:${b}`).join(' OR '); brandQuery = `(${brandQuery})`; } let categoryQuery = ''; if (category) { categoryQuery = categoryArray.map(c => `category_name:${c}`).join(' OR '); categoryQuery = `(${categoryQuery})`; } let priceQuery = ''; if (priceFrom && priceTo) { priceQuery = `price_f:[${priceFrom} TO ${priceTo}]`; } else if (priceFrom) { priceQuery = `price_f:[${priceFrom} TO *]`; } else if (priceTo) { priceQuery = `price_f:[* TO ${priceTo}]`; } let combinedQuery = ''; let combinedQueryPrice = `${priceQuery}`; if (brand && category && priceFrom || priceTo) { combinedQuery = `${brandQuery} AND ${categoryQuery} `; } else if (brand && category) { combinedQuery = `${brandQuery} AND ${categoryQuery}`; } else if (brand && priceFrom || priceTo) { combinedQuery = `${brandQuery}`; } else if (category && priceFrom || priceTo) { combinedQuery = `${categoryQuery}`; } else if (brand) { combinedQuery = brandQuery; } else if (category) { combinedQuery = categoryQuery; } if (combinedQuery && priceFrom || priceTo) { const response = await fetchVariantSolr(`id:${item.product_id} AND ${combinedQuery}`); const product = response.response.docs[0]; const product_id = product.id; const response2 = await fetchPromoItemsSolr(`type_value_s:${Array.isArray(slug) ? slug[0] : slug} AND product_ids:${product_id} AND ${combinedQueryPrice}`,0,100); return response2; }else if(combinedQuery){ const response = await fetchVariantSolr(`id:${item.product_id} AND ${combinedQuery}`); const product = response.response.docs[0]; const product_id = product.id; const response2 = await fetchPromoItemsSolr(`type_value_s:${Array.isArray(slug) ? slug[0] : slug} AND product_ids:${product_id} `,0,100); return response2; } else { const response = await fetchPromoItemsSolr(`id:${item.id}`,0,100); return response; } } catch (fetchError) { return []; } }); const promoDataArray = await Promise.all(promoDataPromises); const mergedPromoData = promoDataArray.reduce((accumulator, currentValue) => accumulator.concat(currentValue), []); setPromoData(mergedPromoData); const dataBrandCategoryPromises = promoDataArray.map(async (promoData) => { if (promoData) { const dataBrandCategory = promoData.map(async (item) => { let response; if(category){ const categoryQuery = categoryArray.map(c => `category_name:${c}`).join(' OR '); response = await fetchVariantSolr(`id:${item.products[0].product_id} AND (${categoryQuery})`); }else{ response = await fetchVariantSolr(`id:${item.products[0].product_id}`) } if (response.response?.docs?.length > 0) { const product = response.response.docs[0]; const manufactureNameS = product.manufacture_name; if (Array.isArray(manufactureNameS)) { for (let i = 0; i < manufactureNameS.length; i += 2) { const brand = manufactureNameS[i]; const qty = 1; const existingBrandIndex = brandsData.findIndex(b => b.brand === brand); if (existingBrandIndex !== -1) { brandsData[existingBrandIndex].qty += qty; } else { brandsData.push({ brand, qty }); } } } const categoryNameS = product.category_name; if (Array.isArray(categoryNameS)) { for (let i = 0; i < categoryNameS.length; i += 2) { const name = categoryNameS[i]; const qty = 1; const existingCategoryIndex = categoriesData.findIndex(c => c.name === name); if (existingCategoryIndex !== -1) { categoriesData[existingCategoryIndex].qty += qty; } else { categoriesData.push({ name, qty }); } } } } }); return Promise.all(dataBrandCategory); } }); await Promise.all(dataBrandCategoryPromises); setBrands(brandsData); setCategories(categoriesData); setLoading(false); } catch (loadError) { // console.error("Error loading promo items:", loadError) setLoading(false); } } if (slug) { loadPromo() } },[slug, brand, category, priceFrom, priceTo, currentPage]); function capitalizeFirstLetter(string) { string = string.replace(/_/g, ' '); return string.replace(/(^\w|\s\w)/g, function(match) { return match.toUpperCase(); }); } const handleDeleteFilter = async (source, value) => { let params = { q: router.query.q, orderBy: '', brand: brandValues.join(','), category: categoryValues.join(','), priceFrom: priceFrom || '', priceTo: priceTo || '', }; let brands = brandValues; let catagories = categoryValues; switch (source) { case 'brands': brands = brandValues.filter((item) => item !== value); params.brand = brands.join(','); await setBrandValues(brands); break; case 'category': catagories = categoryValues.filter((item) => item !== value); params.category = catagories.join(','); await setCategoryValues(catagories); break; case 'price': params.priceFrom = ''; params.priceTo = ''; break; case 'delete': params = { q: router.query.q, orderBy: '', brand: '', category: '', priceFrom: '', priceTo: '', }; break; } handleSubmitFilter(params); }; const handleSubmitFilter = (params) => { params = _.pickBy(params, _.identity); params = toQuery(params); router.push(`${slug}?${params}`); }; const visiblePromotions = promoData?.slice( (currentPage-1) * itemsPerPage, currentPage * 12) const toQuery = (obj) => { const str = Object.keys(obj) .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(obj[key])}`) .join('&') return str } const whatPromo = capitalizeFirstLetter(slug) const queryWithoutSlug = _.omit(router.query, ['slug']) const queryString = toQuery(queryWithoutSlug) return (

Promo {whatPromo}

{promoItems.length >= 1 && (
)} {loading ? (
) : promoData && promoItems.length >= 1 ? ( <>
{visiblePromotions?.map((promotion) => (
))}
) : (

Belum ada promo pada kategori ini

)}

Promo {whatPromo}

{loading ? (
) : promoData && promoItems.length >= 1 ? ( <>
{visiblePromotions?.map((promotion) => (
))}
) : (

Belum ada promo pada kategori ini

)}
Barang yang anda cari tidak ada?{' '} Hubungi Kami
) } const FilterChoicesComponent = ({ brandValues, categoryValues, priceFrom, priceTo, handleDeleteFilter, }) => (
{brandValues?.map((value, index) => ( {value} handleDeleteFilter('brands', value)} /> ))} {categoryValues?.map((value, index) => ( {value} handleDeleteFilter('category', value)} /> ))} {priceFrom && priceTo && ( {formatCurrency(priceFrom) + '-' + formatCurrency(priceTo)} handleDeleteFilter('price', priceFrom)} /> )} {brandValues?.length > 0 || categoryValues?.length > 0 || priceFrom || priceTo ? ( ) : ( '' )}
);